<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
</head>
<body>
    <canvas id="physics-canvas" width="500" height="550"></canvas>
    <script>
        const canvas = document.getElementById('physics-canvas');
        const ctx = canvas.getContext('2d');

        // Function to draw an arrowhead on a line
        function drawArrowhead(ctx, fromX, fromY, toX, toY, angle, length) {
            const dx = toX - fromX;
            const dy = toY - fromY;
            const lineAngle = Math.atan2(dy, dx);
            ctx.save();
            ctx.beginPath();
            ctx.translate(toX, toY);
            ctx.rotate(lineAngle);
            ctx.moveTo(0, 0);
            ctx.lineTo(-length, -angle);
            ctx.lineTo(-length, angle);
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        }

        // --- Style setup ---
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 1.5;
        ctx.font = "16px 'Times New Roman'";
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        
        // --- Component Coordinates ---
        const meterX = 250;
        const meterTopY = 40;
        
        const frameCenterX = 250;
        const frameWidth = 120; // 6.0 cm
        const frameHeight = 160; // 8.0 cm
        
        const frameBottomY = 430;
        const frameTopStraightY = frameBottomY - frameHeight; // 270
        const frameLeftX = frameCenterX - frameWidth / 2; // 190
        const frameRightX = frameCenterX + frameWidth / 2; // 310
        
        const notchApexY = frameTopStraightY - 10; // 260
        const notchCornerLeftX = frameCenterX - 10; // 240
        const notchCornerRightX = frameCenterX + 10; // 260

        const threadApexY = 200;
        const hookBottomY = 180;
        const hookCenterY = hookBottomY - 10; // 170

        // 1. Draw Newton Meter
        // Top loop
        ctx.beginPath();
        ctx.arc(meterX, meterTopY, 10, Math.PI, 0);
        ctx.stroke();
        // Body
        ctx.strokeRect(meterX - 10, meterTopY + 10, 20, 100);
        // Scale
        ctx.save();
        ctx.lineWidth = 0.5;
        for (let i = 0; i <= 10; i++) {
            const y = meterTopY + 20 + i * 8;
            const tickLength = (i % 5 === 0) ? 6 : 3;
            ctx.beginPath();
            ctx.moveTo(meterX - tickLength, y);
            ctx.lineTo(meterX + tickLength, y);
            ctx.stroke();
        }
        ctx.restore();
        // Plunger and pointer
        ctx.beginPath();
        ctx.moveTo(meterX, meterTopY + 20);
        ctx.lineTo(meterX, hookCenterY - 20);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(meterX, meterTopY + 60);
        ctx.lineTo(meterX - 10, meterTopY + 60);
        ctx.lineTo(meterX - 15, meterTopY + 65);
        ctx.lineTo(meterX - 10, meterTopY + 70);
        ctx.lineTo(meterX, meterTopY + 70);
        ctx.stroke();
        // Bottom hook
        ctx.beginPath();
        ctx.arc(meterX, hookCenterY, 10, 0, Math.PI, false);
        ctx.moveTo(meterX - 10, hookCenterY);
        ctx.lineTo(meterX - 10, hookCenterY - 10);
        ctx.moveTo(meterX + 10, hookCenterY);
        ctx.lineTo(meterX + 10, hookCenterY - 10);
        ctx.stroke();

        // 2. Draw Insulating Thread
        ctx.beginPath();
        ctx.moveTo(meterX, hookBottomY);
        ctx.lineTo(notchCornerLeftX, frameTopStraightY);
        ctx.moveTo(meterX, hookBottomY);
        ctx.lineTo(notchCornerRightX, frameTopStraightY);
        ctx.stroke();
        
        // 3. Draw Frame
        ctx.beginPath();
        ctx.moveTo(frameLeftX, frameTopStraightY);
        ctx.lineTo(notchCornerLeftX, frameTopStraightY);
        ctx.lineTo(frameCenterX, notchApexY);
        ctx.lineTo(notchCornerRightX, frameTopStraightY);
        ctx.lineTo(frameRightX, frameTopStraightY);
        ctx.lineTo(frameRightX, frameBottomY);
        ctx.lineTo(frameLeftX, frameBottomY);
        ctx.closePath();
        ctx.stroke();

        // 4. Draw Labels and Annotations
        ctx.textAlign = 'left';
        // newton meter
        ctx.fillText("newton meter", meterX + 25, meterTopY + 60);
        ctx.beginPath();
        ctx.moveTo(meterX + 10, meterTopY + 65);
        ctx.lineTo(meterX + 23, meterTopY + 65);
        ctx.stroke();
        
        // insulating thread
        ctx.fillText("insulating thread", frameCenterX + 30, threadApexY + 20);
        ctx.beginPath();
        ctx.moveTo(frameCenterX + 28, threadApexY + 25);
        ctx.lineTo(frameCenterX + 10, threadApexY + 35);
        ctx.stroke();

        // frame
        ctx.fillText("frame", frameRightX + 20, frameTopStraightY + 80);
        ctx.beginPath();
        ctx.moveTo(frameRightX, frameTopStraightY + 85);
        ctx.lineTo(frameRightX + 18, frameTopStraightY + 85);
        ctx.stroke();

        // Dimensions
        // 8.0 cm
        const dim_v_x = frameLeftX - 40;
        ctx.fillText("8.0 cm", dim_v_x - 50, frameTopStraightY + frameHeight / 2);
        ctx.save();
        ctx.setLineDash([3, 3]);
        ctx.beginPath();
        ctx.moveTo(frameLeftX, frameTopStraightY);
        ctx.lineTo(dim_v_x, frameTopStraightY);
        ctx.moveTo(frameLeftX, frameBottomY);
        ctx.lineTo(dim_v_x, frameBottomY);
        ctx.stroke();
        ctx.restore();
        ctx.beginPath();
        ctx.moveTo(dim_v_x, frameTopStraightY);
        ctx.lineTo(dim_v_x, frameBottomY);
        ctx.stroke();
        drawArrowhead(ctx, dim_v_x, frameBottomY, dim_v_x, frameTopStraightY, 4, 10);
        drawArrowhead(ctx, dim_v_x, frameTopStraightY, dim_v_x, frameBottomY, 4, 10);
        
        // 6.0 cm
        ctx.textAlign = 'center';
        const dim_h_y = frameBottomY + 30;
        ctx.fillText("6.0 cm", frameCenterX, dim_h_y + 10);
        ctx.save();
        ctx.setLineDash([3, 3]);
        ctx.beginPath();
        ctx.moveTo(frameLeftX, frameBottomY);
        ctx.lineTo(frameLeftX, dim_h_y);
        ctx.moveTo(frameRightX, frameBottomY);
        ctx.lineTo(frameRightX, dim_h_y);
        ctx.stroke();
        ctx.restore();
        ctx.beginPath();
        ctx.moveTo(frameLeftX, dim_h_y);
        ctx.lineTo(frameRightX, dim_h_y);
        ctx.stroke();
        drawArrowhead(ctx, frameRightX, dim_h_y, frameLeftX, dim_h_y, 4, 10);
        drawArrowhead(ctx, frameLeftX, dim_h_y, frameRightX, dim_h_y, 4, 10);

        // P and Q
        ctx.fillText("P", frameLeftX, frameBottomY + 15);
        ctx.fillText("Q", frameRightX, frameBottomY + 15);

        // Current
        ctx.textAlign = 'right';
        ctx.fillText("5.0 A", frameLeftX - 15, frameTopStraightY + frameHeight * 0.4);
        const arrow_y = frameTopStraightY + frameHeight * 0.5;
        ctx.beginPath();
        ctx.moveTo(frameLeftX, arrow_y);
        ctx.lineTo(frameLeftX, arrow_y + 20);
        ctx.stroke();
        drawArrowhead(ctx, frameLeftX, arrow_y, frameLeftX, arrow_y + 20, 4, 10);

        // Fig. 8.1
        ctx.textAlign = 'center';
        ctx.fillText("Fig. 8.1", frameCenterX, frameBottomY + 60);

    </script>
</body>
</html>